﻿/* *
 * =============================================================================
 * File Name:               Page.xaml.cs
 * Programmer:              Ken Watts
 * Creation Date:           8/3/2008
 * =============================================================================
 * Description:             Class that represents the front page for the app.
 * =============================================================================
 * Modification Date:       8/3/2008 - Initial Revision
 * =============================================================================
 * */

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DigitalLogicSimulator
{
    public partial class Page : UserControl
    {
        System.Windows.Interop.Content content = Application.Current.Host.Content;
        const int k_int_grid_size = 10;
        const int k_int_grid_start = 12;
        const int k_int_timer_interval_ms = 500;
        Button buttonDelete;

        public Page()
        {
            InitializeComponent();
            // wire up key down and full screen changed events
            this.KeyDown += new KeyEventHandler(Page_KeyDown);
            this.Loaded += new RoutedEventHandler(Page_Load);
            this.MouseLeftButtonDown += new MouseButtonEventHandler(Page_MouseLeftButtonDown);
            content.FullScreenChanged += new EventHandler(Content_FullScreenChanged);

            // Get reference to the delete button
            for (int i = 0; i < LayoutRoot.Children.Count; i++)
                if (LayoutRoot.Children[i] is Button)
                {
                    buttonDelete = (Button)LayoutRoot.Children[i];
                    break;
                }
            buttonDelete.IsEnabled = false;

            // Draw a graph-paper like grid background
            Line l;
            Color gridColor = Color.FromArgb(0xff, 0x87, 0xce, 0xfa);
            // Draw the vertical grid lines
            for (int i = k_int_grid_size * (k_int_grid_start+1); i < this.Width; i += k_int_grid_size)
            {
                l = new Line();
                l.Stroke = new SolidColorBrush(gridColor);
                l.StrokeThickness = 1;
                l.X1 = i;
                l.Y1 = 0;
                l.X2 = i;
                l.Y2 = this.Height;
                LayoutRoot.Children.Add(l);
            }
            // Draw the horizontal grid lines
            for (int i = k_int_grid_size; i < this.Height; i += k_int_grid_size)
            {
                l = new Line();
                l.Stroke = new SolidColorBrush(gridColor);
                l.StrokeThickness = 1;
                l.X1 = k_int_grid_size * k_int_grid_start;
                l.Y1 = i;
                l.X2 = this.Width;
                l.Y2 = i;
                LayoutRoot.Children.Add(l);                
            }

            // Add devices
            for (int i = 0; i < 2; i++)
            {
                LayoutRoot.Children.Add(new TwoInputAndGate());
                LayoutRoot.Children.Add(new TwoInputOrGate());
                LayoutRoot.Children.Add(new ConstantHigh());
                LayoutRoot.Children.Add(new ConstantLow());
                LayoutRoot.Children.Add(new LightEmittingDiode());
                LayoutRoot.Children.Add(new PulseGenerator());
                LayoutRoot.Children.Add(new Inverter());
                LayoutRoot.Children.Add(new TwoInputXorGate());
                LayoutRoot.Children.Add(new TwoInputNandGate());
                LayoutRoot.Children.Add(new TwoInputNorGate());
                LayoutRoot.Children.Add(new Switch());
                LayoutRoot.Children.Add(new PushButton());
                LayoutRoot.Children.Add(new HorizontalWire());
                LayoutRoot.Children.Add(new VerticalWire());
                LayoutRoot.Children.Add(new JKFlipFlop());
                LayoutRoot.Children.Add(new DFlipFlop());
            }           
        }

        void Page_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            // Unselect any seleted devices
            if (!e.Handled)
                for (int i = 0; i < LayoutRoot.Children.Count; i++)
                    if (LayoutRoot.Children[i] is Device)
                    {
                        Device d = LayoutRoot.Children[i] as Device;
                        if (d.IsSelected())
                        {
                            d.Unselect();
                            // Update the state of the delete button
                            d.UpdateDeleteButtonState();
                        }
                    }
        }

        void Page_Load(object o, EventArgs args)
        {
            Timer = this.FindName("Timer") as Storyboard;
            Timer.Duration = new TimeSpan(0, 0, 0, 0, k_int_timer_interval_ms);
            Timer.Begin();
        }

        void Page_KeyDown(object sender, KeyEventArgs e)
        {
            // go full screen when F is pressed (esc will take us out of full screen)
            if (e.Key == Key.F)
            {
                content.IsFullScreen = true;
            }
            else if (e.Key == Key.Delete)
            {
                // If a device is selected, remove it
                for (int i = 0; i < LayoutRoot.Children.Count; i++)
                    if (LayoutRoot.Children[i] is Device)
                    {
                        Device d = LayoutRoot.Children[i] as Device;
                        if (d.Focused())
                            // "MessageBox" is not supported in full screen mode yet...
                            d.Delete();
                            // Update the state of the delete button
                            d.UpdateDeleteButtonState();
                    }
            }
        }

        void Content_FullScreenChanged(object sender, EventArgs e)
        {
            //scale content if we are in full screen.
            if (content.IsFullScreen)
            {
                double heightRatio = content.ActualHeight / this.Height;
                double widthRatio = content.ActualWidth / this.Width;
                ScaleTransform scale = new ScaleTransform();
                scale.ScaleX = widthRatio;
                scale.ScaleY = heightRatio;
                this.RenderTransform = scale;
            }
            else
            {
                this.RenderTransform = null;
            }
        }

        void storyboardTimer_Completed(object sender, EventArgs e)
        {
            // Reset the timer        
            Timer.Duration = new TimeSpan(0, 0, 0, 0, k_int_timer_interval_ms);
            Timer.Begin();
            // Call the "tick" method for any pulse generators
            for (int i = 0; i < LayoutRoot.Children.Count; i++)
                if (LayoutRoot.Children[i] is PulseGenerator)
                {
                    PulseGenerator pg = LayoutRoot.Children[i] as PulseGenerator;
                    pg.Tick();
                }

        }

        private void ButtonDelete_Click(object sender, RoutedEventArgs e)
        {
            // Delete any selected devices
            for (int i = 0; i < LayoutRoot.Children.Count; i++)
                if (LayoutRoot.Children[i] is Device)
                {
                    Device d = LayoutRoot.Children[i] as Device;
                    if (d.IsSelected())
                    {
                        // Delete the selected device
                        d.Delete();
                        // Update the state of the delete button
                        d.UpdateDeleteButtonState();
                    }
                }
        }

    }
}
